package com.bootdo.collector.task;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bootdo.collector.utils.ESParse;
import com.bootdo.collector.utils.HttpClient;
import com.bootdo.collector.utils.SSH2;
import com.bootdo.screen.domain.AssetsDO;
import com.bootdo.screen.domain.PtclusterserverDO;
import com.bootdo.screen.domain.PtfaultmonitorDO;
import com.bootdo.screen.domain.PtservicelistDO;
import com.bootdo.screen.service.AssetsService;
import com.bootdo.screen.service.PtclusterserverService;
import com.bootdo.screen.service.PtfaultmonitorService;
import com.bootdo.screen.service.PtservicelistService;
import com.jcraft.jsch.*;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestClient;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import springfox.documentation.service.ApiListing;

import java.io.*;
import java.net.SocketTimeoutException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


public class AmbariCountJob implements Job {
    private final static String AlertUrl = "http://%s:%d/api/v1/clusters/CNPC/alerts?fields=Alert/component_name,Alert/definition_id,Alert/definition_name,Alert/host_name,Alert/id,Alert/instance,Alert/label,Alert/latest_timestamp,Alert/maintenance_state,Alert/original_timestamp,Alert/scope,Alert/service_name,Alert/state,Alert/text&Alert/state.in(CRITICAL,WARNING)&Alert/maintenance_state.in(OFF)&from=0&page_size=20&_=%d";
    private  final  static String ServiceListURl ="http://%s:%d/api/v1/clusters/CNPC/services?fields=ServiceInfo/state,ServiceInfo/maintenance_state,components/ServiceComponentInfo/component_name&minimal_response=true&_=%d";
    private final  static String ESAlertURi = "_cluster/health";

    @Autowired
    private PtservicelistService PtservicelistService;

    @Autowired
    private PtclusterserverService ptclusterserverService;

    @Autowired
    private PtfaultmonitorService ptfaultmonitorService;

    @Autowired
    private RestClient restClient;

    @Autowired
    private AssetsService assetsService;


    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        List<Map<String, Object>> alerts = getBigDataAlerts();
        List<String> services = getBigdataServerList();
        for ( String service: services  ) {
            PtclusterserverDO clusterserver = new PtclusterserverDO();
            PtservicelistDO ptservicel = new  PtservicelistDO();
            clusterserver.setStatus("正常");
            clusterserver.setServer(service);
            clusterserver.setDatetime(new Date());

            ptservicel.setService(service);
            ptservicel.setLocation("M05物理区");
            ptservicel.setStatus("正常");

            for ( Map<String, Object> alert:alerts) {
                if (service.equals(alert.get("service_name"))) {
                    clusterserver.setStatus("告警");
                    ptservicel.setStatus("异常");
                }
            }
            ptclusterserverService.saveUpdate(clusterserver);
            PtservicelistService.saveUpdate(ptservicel);
        }
        // 故障列表
        for ( Map<String, Object> alert:alerts) {
            Map<String,Object> map = new  HashMap<>() ;
            map.put("message",String.valueOf(alert.get("text")));
            Date date = new Date();
            long time = (Long) alert.get("original_timestamp") / 1000;
            date.setTime(time*1000);
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            map.put("datetime",   df.format(date));
            List<PtfaultmonitorDO> pts = ptfaultmonitorService.list(map);
            if (pts.size() == 0) {
                PtfaultmonitorDO  ptf   = new PtfaultmonitorDO();
                ptf.setDatetime(date);
                ptf.setLocation("M05物理区");
                ptf.setMessage(String.valueOf(alert.get("text")));
                ptf.setService(String.valueOf(alert.get("service_name")));
                if ("CRITICAL".equals(String.valueOf(alert.get("state")))) {
                    ptf.setLevel("高危");
                } else if ("WARNING".equals(String.valueOf(alert.get("state")))) {
                    ptf.setLevel("中危");
                } else {
                    ptf.setLevel("低危");
                }
                ptfaultmonitorService.save(ptf);
            }

        }

        // ES 告警
        try {
            Response res = restClient.performRequest("GET", ESAlertURi, Collections.<String, String>emptyMap());
            String status= JSON.parseObject( EntityUtils.toString(res.getEntity())).getString("status");

            Date date = new Date();
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            String datestring = df.format(date);
            Date date2 = df.parse(datestring);
            Map<String,Object> map = new  HashMap<>() ;
            map.put("service","ElasticSearch");
            map.put("datetime",  datestring+" 00:00:00");
            List<PtfaultmonitorDO> pts = ptfaultmonitorService.list(map);
            if (pts.size() == 0) {
                PtfaultmonitorDO  ptf   = new PtfaultmonitorDO();
                ptf.setDatetime(date2);
                ptf.setLocation("M05物理区");
                ptf.setService("ElasticSearch");
                if (status.equals("red")) {
                    ptf.setMessage("ElasticSearch集群，分片不足，发生严重错误");
                    ptf.setLevel("高危");
                    ptfaultmonitorService.save(ptf);
                } else if (status.equals("yellow")) {
                    ptf.setMessage("ElasticSearch集群，分片安全值变化");
                    ptf.setLevel("中危");
                    ptfaultmonitorService.save(ptf);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {

        }


        // 进程报警
        // 磁盘 内存 报警
        Map<String, Object> map = new HashMap<>();
        map.put("maintenance",0);
        List<AssetsDO> assets = assetsService.list(map);
        for (AssetsDO asset: assets ) {
            try {
            Date date = new Date();
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            df.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            String datestring = df.format(date);
            Date date2 = df.parse(datestring);
            Map<String,Object> map2 = new  HashMap<>() ;
            map2.put("datetime",  datestring+" 00:00:00");
            String host = asset.getIp();
            String username = asset.getUsername();
            SSH2 ssh2 = new SSH2();
            ssh2.setHost(host);
            ssh2.setUsername(username);
            int times = 2;
            while (times!=0) {
                try {
                    ssh2.connect();
                    break;
                } catch (JSchException e) {
                    e.printStackTrace();
                }
                times = times-1 ;
            }
            PtfaultmonitorDO  ptf   = new PtfaultmonitorDO();
            ptf.setDatetime(date2);
            ptf.setLocation(asset.getArea());
            ptf.setService(asset.getApp());
            //主机异常
            if (times == 0) {
                String error = "主机 "+ssh2.getIp() + " 失去心跳，状态异常";
                map2.put("message",error);
                List<PtfaultmonitorDO> pts = ptfaultmonitorService.list(map2);
                if (pts.size() == 0) {
                    ptf.setMessage(error);
                    ptf.setLevel("高危");
                    ptfaultmonitorService.save(ptf);
                }
                break;
            }
             //进程异常

            if (asset.getProcess().contains(";")) {
                String[] pss = asset.getProcess().split(";");
                for (int i =0 ;i< pss.length; i++) {
                    String cmd = "ps -ef | grep -v grep | grep ";
                    cmd = cmd + pss[i];
                    System.out.println(cmd);
                    String res = ssh2.run(cmd);
                    System.out.println(res);
                    if (res.equals("")) {
                        String error =  "主机 "+ssh2.getIp() + "的 "+ pss[i]+ " 进程异常";
                        map2.put("message",error);
                        List<PtfaultmonitorDO> pts = ptfaultmonitorService.list(map2);
                        if (pts.size() == 0) {
                            ptf.setMessage(error);
                            ptf.setLevel("中危");
                            ptfaultmonitorService.save(ptf);
                        }
                    }

                }

            }
            //磁盘异常
                String dff = ssh2.run("df -h");
                String[] dfs = dff.split("\n");
                for (int i=0;i<dfs.length;i++) {
                    if (dfs[i].startsWith("/")) {
                        System.out.println(dfs[i]);
                        String[] dfss = dfs[i].split(" ");
                        if (dfss[dfss.length-2].contains("%")) {

                            if (Integer.valueOf(dfss[dfss.length-2].replace("%","")) > 90) {
                                String error =  "主机 "+ssh2.getIp()+":"+dfss[dfss.length-1] +"目录容量已用"+ dfss[dfss.length-2];
                                map2.put("message",error);
                                List<PtfaultmonitorDO> pts = ptfaultmonitorService.list(map2);
                                if (pts.size() == 0) {
                                    ptf.setMessage(error);
                                    ptf.setLevel("高危");
                                    ptfaultmonitorService.save(ptf);
                                }
                                continue;

                            } else if (Integer.valueOf(dfss[dfss.length-2].replace("%","")) > 75) {
                                String error =  "主机 "+ssh2.getIp()+":"+dfss[dfss.length-1] +"目录容量已用"+ dfss[dfss.length-2];
                                map2.put("message",error);
                                List<PtfaultmonitorDO> pts = ptfaultmonitorService.list(map2);
                                if (pts.size() == 0) {
                                    ptf.setMessage(error);
                                    ptf.setLevel("中危");
                                    ptfaultmonitorService.save(ptf);
                                }

                            }
                        }
                    }
                }







            } catch (ParseException e) {
                e.printStackTrace();
            }


        }


    }

    public static void main(String[] args) {


    }


    public static  List<String> getBigdataServerList() {
        String res = HttpClient.get(HttpClient.urlformat(ServiceListURl));
        List list = new ArrayList<>();
        if (!res.equals("")) {
            JSONArray alerts = JSON.parseObject(res).getJSONArray("items");
            for(int i=0;i<alerts.size();i++){
                JSONObject ms = alerts.getJSONObject(i).getJSONObject("ServiceInfo");
                list.add(ms.getString("service_name"));
            }

        }
        return  list;
    }

    public static List<Map<String,Object>> getBigDataAlerts() {
        String res = HttpClient.get(HttpClient.urlformat(AlertUrl));
        List<Map<String,Object>> list = new ArrayList<>();
        if (!res.equals("")) {
            JSONArray alerts = JSON.parseObject(res).getJSONArray("items");
            for(int i=0;i<alerts.size();i++){
                Map<String ,Object>  map = new HashMap<>();
                JSONObject ms = alerts.getJSONObject(i).getJSONObject("Alert");
                map.put("service_name",ms.getString("service_name"));
                map.put("state",ms.getString("state"));
                map.put("definition_name",ms.getString("definition_name"));
                String text = ms.getString("text");
                text = text.replace("\n"," ");
                map.put("text",text);
                map.put("original_timestamp",ms.getLong("original_timestamp"));
                list.add(map);
            }

        }
        return  list;
    }


}
